﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using NetMicro.Core.Extensions;
using NetMicro.Domains.Extensions;
using NetMicro.Domains.Strategy;

namespace NetMicro.Domains.Repositories
{
    /// <summary>
    /// 仓储抽象类
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    public abstract class Repository<TEntity, TKey> : RepositoryBase, IRepository<TEntity, TKey> where TEntity : EntityBase<TKey>, new()
    {
        private readonly ISqlTableFactory _multiTableFactory;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="multiTableFactory"></param>
        protected Repository(DbContext context, ISqlTableFactory multiTableFactory)
            : base(context)
        {
            _multiTableFactory = multiTableFactory;


        }
        #region 查询

        /// <summary>
        /// 获取行数
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual int Count(Expression<Func<TEntity, bool>> whereExpression = null, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).Count();

        /// <summary>
        /// 获取行数
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression = null, object subTableValue = null, SqlSugarClient client = null) =>
            await SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).CountAsync();



        /// <summary>
        /// 根据主键查询
        /// </summary>
        /// <param name="id"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>

        public virtual TEntity GetById(TKey id, object subTableValue = null, SqlSugarClient client = null)
            => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).InSingle(id);
        /// <summary>
        ///  根据主键查询
        /// </summary>
        /// <param name="id"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<TEntity> GetByIdAsync(TKey id, object subTableValue = null, SqlSugarClient client = null) 
            => await SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).InSingleAsync(id);



        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool IsAny(Expression<Func<TEntity, bool>> whereExpression = null, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).Any();

        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> IsAnyAsync(Expression<Func<TEntity, bool>> whereExpression = null, object subTableValue = null, SqlSugarClient client = null) => await SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).AnyAsync();

        /// <summary>
        /// 获取list
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="selector"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual List<TEntity> GetList(Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, TEntity>> selector = null, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).Select(selector).ToList();
        /// <summary>
        /// 获取list
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="selector"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, TEntity>> selector = null, object subTableValue = null, SqlSugarClient client = null) => await SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).Select(selector).ToListAsync();



        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="PageIndex"></param>
        /// <param name="PageSize"></param>
        /// <param name="orderByType"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="selector"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>

        public virtual PagerList<TEntity> GetPageList(Expression<Func<TEntity, bool>> whereExpression = null, int PageIndex = 1, int PageSize = 20, OrderByType orderByType = OrderByType.Asc, Expression<Func<TEntity, object>> orderByExpression = null, Expression<Func<TEntity, TEntity>> selector = null, object subTableValue = null, SqlSugarClient client = null)
            => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(ExpressionIsDelete(whereExpression)).Select(selector).ToPagedList(PageIndex, PageSize);
        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="conditionalList"></param>
        /// <param name="PageIndex"></param>
        /// <param name="PageSize"></param>
        /// <param name="orderByType"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="selector"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual PagerList<TEntity> GetPageList(List<IConditionalModel> conditionalList, int PageIndex = 1, int PageSize = 20, OrderByType orderByType = OrderByType.Asc, Expression<Func<TEntity, object>> orderByExpression = null, Expression<Func<TEntity, TEntity>> selector = null, object subTableValue = null, SqlSugarClient client = null)
            => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(conditionalList).Select(selector).ToPagedList(PageIndex, PageSize);
        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="PageIndex"></param>
        /// <param name="PageSize"></param>
        /// <param name="orderByType"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="selector"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual Task<PagerList<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression = null, int PageIndex = 1, int PageSize = 20, OrderByType orderByType = OrderByType.Asc, Expression<Func<TEntity, object>> orderByExpression = null, Expression<Func<TEntity, TEntity>> selector = null, object subTableValue = null, SqlSugarClient client = null)
            => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(ExpressionIsDelete(whereExpression)).Select(selector).ToPagedListAsync(PageIndex, PageSize);
        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="conditionalList"></param>
        /// <param name="PageIndex"></param>
        /// <param name="PageSize"></param>
        /// <param name="orderByType"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="selector"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual Task<PagerList<TEntity>> GetPageListAsync(List<IConditionalModel> conditionalList, int PageIndex = 1, int PageSize = 20, OrderByType orderByType = OrderByType.Asc, Expression<Func<TEntity, object>> orderByExpression = null, Expression<Func<TEntity, TEntity>> selector = null, object subTableValue = null, SqlSugarClient client = null)
            => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(conditionalList).Select(selector).ToPagedListAsync(PageIndex, PageSize);



        /// <summary>
        /// 获取第一条
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="selector"></param>
        /// <param name="orderByType"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual TEntity First(Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, TEntity>> selector = null, OrderByType orderByType = OrderByType.Asc, Expression<Func<TEntity, object>> orderByExpression = null, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).OrderByIF(orderByExpression != null, orderByExpression, orderByType).Select(selector).First(ExpressionIsDelete(whereExpression));
        /// <summary>
        /// 获取第一条
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="selector"></param>
        /// <param name="orderByType"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, TEntity>> selector = null, OrderByType orderByType = OrderByType.Asc, Expression<Func<TEntity, object>> orderByExpression = null, object subTableValue = null, SqlSugarClient client = null) => await SugarClient(client).Queryable<TEntity>().AS(GetTableName(subTableValue)).OrderByIF(orderByExpression != null, orderByExpression, orderByType).Select(selector).FirstAsync(ExpressionIsDelete(whereExpression));

        #endregion

        #region 插入
        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="insertObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool Insert(TEntity insertObj, object subTableValue = null, SqlSugarClient client = null)
        {
            insertObj.Init();
            return SugarClient(client).Insertable(insertObj).AS(GetTableName(subTableValue)).ExecuteCommand() > 0;
        }
        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="insertObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool InsertRange(List<TEntity> insertObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            insertObjs.ForEach(m => m.Init());
            if (client?.Ado.Transaction != null)
            {
                return SugarClient(client).Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommand() > 0;
            }
            var db = SugarClient(client);
            var result = db.UseTran(() =>
              {
                  db.Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
              });
            return result.IsSuccess;
        }
        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="insertObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool InsertRange(TEntity[] insertObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            foreach (TEntity item in insertObjs)
            {
                item.Init();
            }
            if (client?.Ado.Transaction != null)
            {
                return SugarClient(client).Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommand() > 0;
            }
            var db = SugarClient(client);
            var result = db.UseTran(() =>
            {
                db.Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
            });
            return result.IsSuccess;
        }
        /// <summary>
        /// 插入返回标识
        /// </summary>
        /// <param name="insertObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual int InsertReturnIdentity(TEntity insertObj, object subTableValue = null, SqlSugarClient client = null)
        {
            insertObj.Init();
            return SugarClient(client).Insertable(insertObj).AS(GetTableName(subTableValue)).ExecuteReturnIdentity();
        }

        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="insertObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> InsertAsync(TEntity insertObj, object subTableValue = null, SqlSugarClient client = null)
        {
            insertObj.Init();
            return await SugarClient(client).Insertable(insertObj).AS(GetTableName(subTableValue)).EnableDiffLogEvent().ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="insertObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> InsertRangeAsync(List<TEntity> insertObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            insertObjs.ForEach(m => m.Init());
            if (client?.Ado.Transaction != null)
            {
                return await SugarClient(client).Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommandAsync() > 0;
            }
            var db = SugarClient(client);
            var result = await db.UseTranAsync(() =>
             {
                 db.Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
                 return Task.CompletedTask;
             });
            return result.IsSuccess;
        }

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="insertObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> InsertRangeAsync(TEntity[] insertObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            foreach (TEntity item in insertObjs)
            {
                item.Init();
            }
            if (client?.Ado.Transaction != null)
            {
                return await SugarClient(client).Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommandAsync() > 0;
            }
            var db = SugarClient(client);
            var result = await db.UseTranAsync(() =>
            {
                db.Insertable(insertObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
                return Task.CompletedTask;
            });
            return result.IsSuccess;
        }

        /// <summary>
        /// 插入返回标识
        /// </summary>
        /// <param name="insertObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<int> InsertReturnIdentityAsync(TEntity insertObj, object subTableValue = null, SqlSugarClient client = null)
        {
            insertObj.Init();
            return await SugarClient(client).Insertable(insertObj).AS(GetTableName(subTableValue)).ExecuteReturnIdentityAsync();
        }
        #endregion

        #region 修改
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool Update(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression, object subTableValue = null, SqlSugarClient client = null)
            => SugarClient(client).Updateable(columns).AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).ExecuteCommand() > 0;
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="updateObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool Update(TEntity updateObj, object subTableValue = null, SqlSugarClient client = null)
        {
            updateObj.UpdateInit(updateObj);
            return SugarClient(client).Updateable(updateObj).AS(GetTableName(subTableValue)).ExecuteCommand() > 0;
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="updateObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool UpdateRange(List<TEntity> updateObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            foreach (var item in updateObjs)
            {
                item.UpdateInit(item);
            }
            if (client?.Ado.Transaction != null)
            {
                return SugarClient(client).Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommand() > 0;
            }
            var db = SugarClient(client);
            var result = db.UseTran(() =>
            {
                db.Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
            });
            return result.IsSuccess;
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="updateObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool UpdateRange(TEntity[] updateObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            foreach (var item in updateObjs)
            {
                item.UpdateInit(item);
            }
            if (client?.Ado.Transaction != null)
            {
                return SugarClient(client).Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommand() > 0;
            }
            var db = SugarClient(client);
            var result = db.UseTran(() =>
            {
                db.Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
            });
            return result.IsSuccess;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression, object subTableValue = null, SqlSugarClient client = null)
        {
            columns = columns.EntityBaseUpdateCombine<TEntity, TKey>();
            return await SugarClient(client).Updateable(columns).AS(GetTableName(subTableValue)).Where(ExpressionIsDelete(whereExpression)).ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="updateObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateAsync(TEntity updateObj, object subTableValue = null, SqlSugarClient client = null)
        {
            updateObj.UpdateInit(updateObj);
            return await SugarClient(client).Updateable(updateObj).AS(GetTableName(subTableValue)).ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="updateObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateRangeAsync(List<TEntity> updateObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            foreach (var item in updateObjs)
            {
                item.UpdateInit(item);
            }
            if (client?.Ado.Transaction != null)
            {
                return await SugarClient(client).Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommandAsync() > 0;
            }
            var db = SugarClient(client);
            var result = await db.UseTranAsync(() =>
             {
                 db.Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
                 return Task.CompletedTask;
             });
            return result.IsSuccess;
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="updateObjs"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateRangeAsync(TEntity[] updateObjs, object subTableValue = null, SqlSugarClient client = null)
        {
            foreach (var item in updateObjs)
            {
                item.UpdateInit(item);
            }
            if (client?.Ado.Transaction != null)
            {
                return await SugarClient(client).Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommandAsync() > 0;
            }
            var db = SugarClient(client);
            var result = await db.UseTranAsync(() =>
            {
                db.Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommand();
                return Task.CompletedTask;
            });
            return result.IsSuccess;
        }
        #endregion


        #region 删除
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool Delete(Expression<Func<TEntity, bool>> whereExpression, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).Where(whereExpression).ExecuteCommand() > 0;
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="deleteObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool Delete(TEntity deleteObj, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).Where(deleteObj).ExecuteCommand() > 0;
        /// <summary>
        /// 主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool DeleteById(TKey id, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).In(id).ExecuteCommand() > 0;
        /// <summary>
        /// 主键批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool DeleteByIds(TKey[] ids, object subTableValue = null, SqlSugarClient client = null) => SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).In(ids).ExecuteCommand() > 0;
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>

        public virtual async Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression, object subTableValue = null, SqlSugarClient client = null) => await SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).Where(whereExpression).ExecuteCommandAsync() > 0;
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="deleteObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteAsync(TEntity deleteObj, object subTableValue = null, SqlSugarClient client = null) => await SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).Where(deleteObj).ExecuteCommandAsync() > 0;
        /// <summary>
        /// 主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteByIdAsync(TKey id, object subTableValue = null, SqlSugarClient client = null) => await SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).In(id).ExecuteCommandAsync() > 0;
        /// <summary>
        /// 主键批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteByIdsAsync(TKey[] ids, object subTableValue = null, SqlSugarClient client = null) => await SugarClient(client).Deleteable<TEntity>().AS(GetTableName(subTableValue)).In(ids).ExecuteCommandAsync() > 0;
        #endregion

        #region 假删除
        /// <summary>
        /// 假删除
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool SoftDelete(Expression<Func<TEntity, bool>> whereExpression = null, object subTableValue = null, SqlSugarClient client = null)
        {
            return SugarClient(client).Updateable<TEntity>().AS(GetTableName(subTableValue))
                      .Where(ExpressionIsDelete(whereExpression))
                      .SetColumns(it => new TEntity { IsDeleted = true }).ExecuteCommand() > 0;
        }
        /// <summary>
        /// 假删除
        /// </summary>
        /// <param name="deleteObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>

        public virtual bool SoftDelete(TEntity deleteObj, object subTableValue = null, SqlSugarClient client = null)
        {
            deleteObj.SoftDeleteInit(deleteObj);
            return SugarClient(client).Updateable(deleteObj).AS(GetTableName(subTableValue)).UpdateColumns(it => new { it.IsDeleted }).ExecuteCommand() > 0;
        }
        /// <summary>
        /// 主键假删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool SoftDeleteById(TKey id, object subTableValue = null, SqlSugarClient client = null)
        {
            Entity<TKey> entity = new Entity<TKey> { Id = id };
            entity.SoftDeleteInit(entity);
            return SugarClient(client).Updateable<TEntity>(entity).AS(GetTableName(subTableValue)).UpdateColumns(it => new { it.IsDeleted }).ExecuteCommand() > 0;
        }
        /// <summary>
        /// 主键批量假删除
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual bool SoftDeleteByIds(TKey[] ids, object subTableValue = null, SqlSugarClient client = null)
        {
            List<Entity<TKey>> updateObjs = new List<Entity<TKey>>();
            foreach (var id in ids)
            {
                Entity<TKey> entity = new Entity<TKey> { Id = id };
                entity.SoftDeleteInit(entity);
                updateObjs.Add(entity);
            }
            return SugarClient(client).Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommand() > 0;
        }
        /// <summary>
        /// 假删除
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> SoftDeleteAsync(Expression<Func<TEntity, bool>> whereExpression = null, object subTableValue = null, SqlSugarClient client = null)
        {
            return await SugarClient(client).Updateable<TEntity>().AS(GetTableName(subTableValue))
                      .Where(ExpressionIsDelete(whereExpression))
                      .SetColumns(it => new TEntity { IsDeleted = true }).ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 假删除
        /// </summary>
        /// <param name="deleteObj"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> SoftDeleteAsync(TEntity deleteObj, object subTableValue = null, SqlSugarClient client = null)
        {
            deleteObj.SoftDeleteInit(deleteObj);
            return await SugarClient(client).Updateable(deleteObj).AS(GetTableName(subTableValue)).UpdateColumns(it => new { it.IsDeleted }).ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 主键假删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> SoftDeleteByIdAsync(TKey id, object subTableValue = null, SqlSugarClient client = null)
        {
            TEntity entity = new TEntity { Id = id };
            entity.SoftDeleteInit(entity);
            return await SugarClient(client).Updateable(entity).AS(GetTableName(subTableValue)).ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 主键批量假删除
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="subTableValue"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public virtual async Task<bool> SoftDeleteByIdsAsync(TKey[] ids, object subTableValue = null, SqlSugarClient client = null)
        {
            List<TEntity> updateObjs = new List<TEntity>();
            foreach (var id in ids)
            {
                TEntity entity = new TEntity { Id = id };
                entity.SoftDeleteInit(entity);
                updateObjs.Add(entity);
            }
            return await SugarClient(client).Updateable(updateObjs).AS(GetTableName(subTableValue)).ExecuteCommandAsync() > 0;

        }
        #endregion


        #region 扩展方法


        /// <summary>
        /// 获取分表querytable
        /// </summary>
        /// <param name="subTableValue"></param>
        /// <returns></returns>
        protected virtual string GetTableName(object subTableValue)
        {
            string table = _multiTableFactory.GetTableName(SugarClient(), typeof(TEntity), subTableValue);

            return table;
        }
        /// <summary>
        /// 添加逻辑删除
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public Expression<Func<TEntity, bool>> ExpressionIsDelete(Expression<Func<TEntity, bool>> whereExpression)
        {
            Expression<Func<TEntity, bool>> isDelete = it => !it.IsDeleted;
            if (whereExpression == null)
            {
                whereExpression = isDelete;
            }
            else
            {
                whereExpression = isDelete.And(whereExpression);
            }
            return whereExpression;
        }
        #endregion

    }
}
